#include "MianCode.h"
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QPushButton>
#include <QHBoxLayout>
#include <QApplication>
#include <QFileDialog>     // 文件对话框类，用于打开本地文件
#include <QPixmap>         // 用于处理图片的类
#include <QDebug>          // 打印调试信息
#include <QResizeEvent>    // 用于处理窗口大小调整事件
#include <QImage>          // 图片数据类型
#include <QTimer>          // 定时器类
#include <QFile>           // 文件读写操作类
#include "../OpencvDeal/GeometricTransformer/GeometricTransformer.h"
#include "../OpencvUtils/OpencvUtils.h"
#include "../OpencvDeal/Filtering_and_smoothing/FilterUtils.h"
#include "../OpencvDeal/MorphologyUtils/MorphologyUtils.h"
#include "../OpencvDeal/EdgeDetector/EdgeDetector.h"
MianCode::MianCode(QWidget *parent)
        : QMainWindow(parent)
{
    setWindowTitle("主窗口");
    resize(800, 600);
    // ======================== 中心窗口主容器 ========================
    QWidget *central = new QWidget(this);
    this->setCentralWidget(central);

    // 主垂直布局：上（Top）+ 中间（Left+Center+Right）+ 下（Bottom）
    QVBoxLayout *mainLayout = new QVBoxLayout(central);
    mainLayout->setSpacing(5);
    mainLayout->setContentsMargins(0, 0, 0, 0);

    // ======================== 顶部 ========================
    topWidgetUI = new TopWidgetUI(this);
    topWidgetUI->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    mainLayout->addWidget(topWidgetUI, 10); // 上部占 10%

    // ======================== 中间区域 ========================
    QWidget *middleWidget = new QWidget(this);
    QHBoxLayout *middleLayout = new QHBoxLayout(middleWidget);
    middleLayout->setSpacing(5);
    middleLayout->setContentsMargins(0, 0, 0, 0);

    // 左侧
    leftWidgetUI = new LeftWidgetUI(this);
    leftWidgetUI->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
    middleLayout->addWidget(leftWidgetUI, 15); // 左侧占 15%

    // 中间
    centerWidgetUI = new CenterWidgetUI(this);
    centerWidgetUI->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    middleLayout->addWidget(centerWidgetUI, 70); // 中间占 70%

    // 右侧
    rightWidgetUI = new RightWidgetUI(this);
    rightWidgetUI->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
    middleLayout->addWidget(rightWidgetUI, 15); // 右侧占 15%

    mainLayout->addWidget(middleWidget, 85); // 中间占 85%

    // ======================== 底部 ========================
    bottomWidgetUI = new BottomWidgetUI(this);
    bottomWidgetUI->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    mainLayout->addWidget(bottomWidgetUI, 5); // 底部占 5%

    // 实现按钮与槽函数的关联
    connect(centerWidgetUI->uploadBtn,&QPushButton::clicked, this, &MianCode::uploadBtnClickedFunction);
    connect(centerWidgetUI->cameraBtn,&QPushButton::clicked, this, &MianCode::onCameraButtonClicked);
    // 如果点击了展示结果按钮操作
    connect(centerWidgetUI->toggleBtn,&QPushButton::clicked, this, &MianCode::onToggleResultDisplayClicked);

    connect(rightWidgetUI, &RightWidgetUI::sliderActionRequested,
            this, &MianCode::onSliderActionRequested);

}

void MianCode::uploadBtnClickedFunction()
{
    QMessageBox::information(this, "提示", "上传图片按钮被点击了！");
    QString path = QFileDialog::getOpenFileName(this, "选择图片", "", "Images (*.png *.jpg *.jpeg)");
    // 如果用户确实选择了图片（非空路径）
    if (!path.isEmpty()) {
        // 使用路径加载图片，并保存到 originalInputPixmap（原始图像副本）
        centerWidgetUI->originalInputPixmap = QPixmap(path);
        // 将加载的图片缩放显示到 QLabel 中，保持比例、平滑变换
        centerWidgetUI->inputImageLabel->setPixmap(centerWidgetUI->originalInputPixmap.scaled(
                centerWidgetUI->inputImageLabel->size(),                 // 缩放目标大小：当前标签大小
                Qt::KeepAspectRatio,            // 保持原始宽高比例
                Qt::SmoothTransformation));         // 使用平滑缩放算法
        // 如果当前正在使用摄像头，调用 toggleCamera 关闭摄像头，防止图片与摄像头图像冲突
        if (centerWidgetUI->cameraRunning){// 如果摄像头是开着的,那么就要进行关闭
            //toggleCamera();
            qDebug() << "toggleCamera() called";
        }
        centerWidgetUI->showingProcessedResult = true; // 设置标志，表示当前正在处理原始图片
        // 备份一个原始图片副本，用于后续处理
        centerWidgetUI->processedResultPixmap = centerWidgetUI->originalInputPixmap;

    }
}

void MianCode::onCameraButtonClicked()
{
    /*
     * 实现打开摄像头的相关操作
     * */
    QMessageBox::information(this, "提示", "摄像头按钮被点击了！");
    centerWidgetUI->onCameraButtonClicked();
}

void MianCode::onToggleResultDisplayClicked()
{
    /*
     * 实现展示结果按钮的相关操作
     *点击结果按钮实现结果的展示
     */
    QMessageBox::information(this, "提示", "展示结果按钮被点击了！");
    centerWidgetUI->toggleResultDisplay();
}


void MianCode::onSliderActionRequested(const QString &mode, QSlider *slider, int value) {
    if (centerWidgetUI->originalInputPixmap.isNull()) return;

    // 将 QPixmap 转为 cv::Mat
    cv::Mat originalMat = QPixmapToCvMat(centerWidgetUI->originalInputPixmap);
    cv::Mat result;

    double param = value / 10.0; // 假设 slider1 范围 0~10 映射到 0~1
    qDebug() << "[MainCode] 获取到的参数：" << param;

    int ksize = 3 + int(param * 20); // 映射为 3~23
    if (ksize % 2 == 0) {
        ksize += 1; // 确保奇数
    }

    if (mode == "缩放") {
        qDebug() << "[MainCode] 缩放操作，值：" << value;
        // 使用 GeometricTransformer::Scale 进行缩放
        // scaleX 和 scaleY = 1 + param, 最小 1.0 表示不缩放
        try {
            result = GeometricTransformer::Scale(originalMat, 1.0 + param, 1.0 + param, cv::INTER_LINEAR);
        } catch (const std::exception &e) {
            qDebug() << "[MainCode] 缩放异常：" << e.what();
            return;
        }
    }
    else if (mode == "旋转") {
        qDebug() << "[MainCode] 旋转操作，值：" << value;
        cv::Point2f center(originalMat.cols / 2.0f, originalMat.rows / 2.0f);
        double angle = param * 360.0; // slider 映射角度
        cv::Matx23f M = GeometricTransformer::MakeRotationMatrix(angle, center, 1.0);
        cv::warpAffine(originalMat, result, cv::Mat(M), originalMat.size());
    }
    else if (mode == "透视") {
        qDebug() << "[MainCode] 透视操作，值：" << value;
        // 先定义源点（原图四个角）
        std::vector<cv::Point2f> srcPts{
                {0.0f, 0.0f},
                {float(originalMat.cols - 1), 0.0f},
                {float(originalMat.cols - 1), float(originalMat.rows - 1)},
                {0.0f, float(originalMat.rows - 1)}
        };

        // 定义目标点（偏移一些点实现透视效果）
        float offset = param * 50.0f; // slider值映射偏移量
        std::vector<cv::Point2f> dstPts{
                {0.0f + offset, 0.0f + offset},
                {float(originalMat.cols - 1) - offset, 0.0f + offset},
                {float(originalMat.cols - 1) - offset, float(originalMat.rows - 1) - offset},
                {0.0f + offset, float(originalMat.rows - 1) - offset}
        };

        try {
            cv::Matx33f H = GeometricTransformer::MakePerspectiveMatrix(srcPts, dstPts);
            cv::warpPerspective(originalMat, result, cv::Mat(H), originalMat.size());
        } catch (const std::exception &e) {
            qDebug() << "[MainCode] 透视异常：" << e.what();
            return;
        }
    }
    else if (mode == "均值滤波") {
        try {
            result = FilterUtils::meanBlur(originalMat, ksize); // 直接赋给 result
        } catch (const std::exception &e) {
            qDebug() << "[MainCode] 均值滤波异常：" << e.what();
            return;
        }
    }
    else if (mode == "中值滤波") {
        try {
            result = FilterUtils::medianBlur(originalMat, ksize); // 直接赋给 result
        } catch (const std::exception &e) {
            qDebug() << "[MainCode] 中值滤波异常：" << e.what();
            return;
        }
    }
    else if (mode == "高斯滤波") {
        try {
            result = FilterUtils::gaussianBlur(originalMat, ksize); // 直接赋给 result
        } catch (const std::exception &e) {
            qDebug() << "[MainCode] 高斯滤波异常：" << e.what();
            return;
        }
    }
    else if (mode == "双边滤波") {
        try {
            result = FilterUtils::bilateralFilter(originalMat, ksize); //
        }catch (const std::exception &e) {
            qDebug() << "[MainCode] 双边滤波异常：" << e.what();
        }
     }
    /*
     * 均值滤波、中值滤波、高斯滤波：核大小越大，模糊越明显。
     * 双边滤波：ksize 控制邻域大小，sigmaColor 控制颜色相似度范围，sigmaSpace 控制空间邻域大小。
     * param 可以直接控制滤波强度，实现滑条实时控制效果。
     * */

    else if(mode == "腐蚀"){
        try {
            result =  MorphologyUtils::erode(originalMat, ksize, MorphologyUtils::RECT);  // 使用矩形核，
        }catch (const std::exception &e) {
            qDebug() << "[MainCode] 双边滤波异常：" << e.what();
        }
    }
    else if(mode == "膨胀"){
        try {
            result =  MorphologyUtils::dilate(originalMat, ksize, MorphologyUtils::ELLIPSE);  // 使用椭圆核
        }catch (const std::exception &e) {
            qDebug() << "[MainCode] 双边滤波异常：" << e.what();
        }
    }
    else if(mode == "开运算"){
        try {
            result =  MorphologyUtils::open(originalMat, ksize, MorphologyUtils::CROSS);  // 使用十字核
        }catch (const std::exception &e) {
            qDebug() << "[MainCode] 双边滤波异常：" << e.what();
        }
    }
    else if(mode == "闭运算"){
        try {
            result =  MorphologyUtils::close(originalMat, ksize, MorphologyUtils::RECT);  // 使用矩形核
        }catch (const std::exception &e) {
            qDebug() << "[MainCode] 双边滤波异常：" << e.what();
        }
    }
    else if (mode == "Canny边缘") {
        try {
            result =  EdgeDetector::CannyDetect(originalMat, 100, 200,ksize);
        }catch (const std::exception &e) {
            qDebug() << "[MainCode] Canny边缘：" << e.what();
        }
    }
    else if (mode == "Sobel边缘") {
        try {
            result =  EdgeDetector::SobelDetect(originalMat, 1, 2,ksize);
        }catch (const std::exception &e) {
            qDebug() << "[MainCode] Sobel边缘：" << e.what();
        }
    }
    else if (mode=="Laplacian边缘"){
        try {
            result =  EdgeDetector::LaplacianDetect(originalMat, ksize);
        }catch (const std::exception &e) {
            qDebug() << "[MainCode] Laplacian边缘：" << e.what();
        }
    }
    // 平移和透视可以按之前方法添加
    // 转回 QPixmap 并显示
    if (!result.empty()) {
        centerWidgetUI->resultImageLabel->setPixmap(
                CvMatToQPixmap(result).scaled(
                        centerWidgetUI->resultImageLabel->size(),
                        Qt::KeepAspectRatio,
                        Qt::SmoothTransformation
                )
        );
    }
}

